<template>
  <div class="data-processing-container">
    <!-- 页面头部 -->
    <div class="page-header">
      <h1 class="page-title">
        <i class="el-icon-data-line"></i>
        数据处理与特征工程
      </h1>
      <p class="page-subtitle">电力负荷数据从原始状态到可用于模型训练的转化过程</p>
    </div>

    <!-- 数据上传区域 -->
    <el-card class="upload-card" shadow="hover">
      <div slot="header" class="card-header">
        <span><i class="el-icon-upload"></i> 数据上传</span>
      </div>

      <el-upload class="upload-dragger" drag action="#" :before-upload="handleFileUpload" :show-file-list="false"
        accept=".csv,.xlsx,.xls">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖拽到此处，或<em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          支持 CSV、Excel 格式，文件大小不超过 50MB
        </div>
      </el-upload>

      <div v-if="uploadedFile" class="uploaded-file-info">
        <el-tag type="success">
          <i class="el-icon-document"></i>
          {{ uploadedFile.name }}
        </el-tag>
        <span class="file-size">{{ formatFileSize(uploadedFile.size) }}</span>
      </div>
    </el-card>

    <!-- 数据预览区域 -->
    <el-card v-if="rawData.length > 0" class="preview-card" shadow="hover">
      <div slot="header" class="card-header">
        <span><i class="el-icon-view"></i> 原始数据预览</span>
        <el-tag type="info">{{ rawData.length }} 条记录</el-tag>
      </div>

      <div class="data-table-container">
        <el-table :data="rawData.slice(0, 10)" border stripe max-height="400">
          <el-table-column prop="value" label="负荷值" width="100" sortable>
            <template #default="{ row }">
              <span class="number-cell">{{ row.value.toFixed(2) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="weather_status" label="天气状态" width="100" sortable></el-table-column>
          <el-table-column prop="temperature" label="温度(°C)" width="100" sortable>
            <template #default="{ row }">
              <span class="temperature-cell" :class="getTemperatureClass(row.temperature)">
                {{ row.temperature }}°C
              </span>
            </template>
          </el-table-column>
          <el-table-column prop="humidity" label="湿度(%)" width="100" sortable></el-table-column>
          <el-table-column prop="wind_speed" label="风速" width="100" sortable></el-table-column>
          <el-table-column prop="wind_direction_angle" label="风向角" width="100" sortable></el-table-column>
          <el-table-column prop="pressure" label="气压" width="100" sortable></el-table-column>
          <el-table-column prop="visibility" label="能见度" width="100" sortable></el-table-column>
          <el-table-column prop="precipitation" label="降水量" width="100" sortable></el-table-column>
          <el-table-column prop="light" label="光照" width="80" sortable></el-table-column>
          <el-table-column prop="holiday" label="节假日" width="80" sortable>
            <template #default="{ row }">
              <el-tag :type="row.holiday === 1 ? 'danger' : 'success'" size="small"> {{ row.holiday === 1 ? '是' : '否' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="minute" label="分钟" width="80" sortable></el-table-column>
          <el-table-column prop="week" label="周" width="80" sortable></el-table-column>
          <el-table-column prop="year" label="年" width="80" sortable></el-table-column>
        </el-table>
      </div>
    </el-card>

    <!-- 数据统计信息 -->
    <el-row v-if="rawData.length > 0" :gutter="20" class="stats-row">
      <el-col :span="8">
        <el-card class="stats-card">
          <div class="stats-item">
            <div class="stats-value">{{ rawData.length }}</div>
            <div class="stats-label">总记录数</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card class="stats-card">
          <div class="stats-item">
            <div class="stats-value">{{ Object.keys(rawData[0] || {}).length }}</div>
            <div class="stats-label">特征维度</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card class="stats-card">
          <div class="stats-item">
            <div class="stats-value">{{ dataQuality.completeness.toFixed(1) }}%</div>
            <div class="stats-label">数据完整性</div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 数据处理配置 -->
    <el-card v-if="rawData.length > 0" class="processing-card" shadow="hover">
      <div slot="header" class="card-header">
        <span><i class="el-icon-setting"></i> 数据处理配置</span>
      </div>

      <el-tabs v-model="activeTab" type="card">
        <!-- 数据清洗 -->
        <el-tab-pane label="数据清洗" name="cleaning">
          <div class="processing-options">
            <el-row :gutter="20">
              <el-col :span="12">
                <h4>缺失值处理</h4>
                <el-radio-group v-model="processingConfig.missingValues">
                  <el-radio label="drop">删除含缺失值的行</el-radio>
                  <el-radio label="fillMean">用均值填充</el-radio>
                  <el-radio label="fillMedian">用中位数填充</el-radio>
                  <el-radio label="fillMode">用众数填充</el-radio>
                </el-radio-group>
              </el-col>
              <el-col :span="12">
                <h4>异常值处理</h4>
                <el-checkbox-group v-model="processingConfig.outlierHandling">
                  <el-checkbox label="removeOutliers">移除异常值</el-checkbox>
                  <el-checkbox label="capOutliers">异常值截断</el-checkbox>
                </el-checkbox-group>
                <div class="outlier-config">
                  <span>异常值阈值：</span>
                  <el-input-number v-model="processingConfig.outlierThreshold" :min="1" :max="5" :step="0.5"
                    size="small"></el-input-number>
                  <span>倍标准差</span>
                </div>
              </el-col>
            </el-row>
          </div>
        </el-tab-pane>

        <!-- 特征工程 -->
        <el-tab-pane label="特征工程" name="feature">
          <div class="processing-options">
            <el-row :gutter="20">
              <el-col :span="12">
                <h4>时间特征</h4>
                <el-checkbox-group v-model="processingConfig.timeFeatures">
                  <el-checkbox label="hour">小时特征</el-checkbox>
                  <el-checkbox label="dayOfWeek">星期特征</el-checkbox>
                  <el-checkbox label="month">月份特征</el-checkbox>
                  <el-checkbox label="season">季节特征</el-checkbox>
                  <el-checkbox label="isWeekend">周末标识</el-checkbox>
                </el-checkbox-group>
              </el-col>
              <el-col :span="12">
                <h4>滞后特征</h4>
                <el-checkbox-group v-model="processingConfig.lagFeatures">
                  <el-checkbox label="lag1">1期滞后</el-checkbox>
                  <el-checkbox label="lag24">24期滞后</el-checkbox>
                  <el-checkbox label="lag168">168期滞后</el-checkbox>
                </el-checkbox-group>
                <div class="lag-config">
                  <span>滚动窗口统计：</span>
                  <el-checkbox-group v-model="processingConfig.rollingStats">
                    <el-checkbox label="mean">滚动均值</el-checkbox>
                    <el-checkbox label="std">滚动标准差</el-checkbox>
                    <el-checkbox label="max">滚动最大值</el-checkbox>
                    <el-checkbox label="min">滚动最小值</el-checkbox>
                  </el-checkbox-group>
                </div>
              </el-col>
            </el-row>
          </div>
        </el-tab-pane>

        <!-- 数据标准化 -->
        <el-tab-pane label="数据标准化" name="normalization">
          <div class="processing-options">
            <el-row :gutter="20">
              <el-col :span="12">
                <h4>标准化方法</h4>
                <el-radio-group v-model="processingConfig.normalization">
                  <el-radio label="none">不进行标准化</el-radio>
                  <el-radio label="standardize">Z-score标准化</el-radio>
                  <el-radio label="minmax">Min-Max标准化</el-radio>
                  <el-radio label="robust">Robust标准化</el-radio>
                </el-radio-group>
              </el-col>
              <el-col :span="12">
                <h4>特征选择</h4>
                <el-checkbox-group v-model="processingConfig.featureSelection">
                  <el-checkbox label="correlation">相关性过滤</el-checkbox>
                  <el-checkbox label="variance">方差过滤</el-checkbox>
                  <el-checkbox label="recursive">递归特征消除</el-checkbox>
                </el-checkbox-group>
                <div class="feature-config">
                  <span>相关性阈值：</span>
                  <el-slider v-model="processingConfig.correlationThreshold" :min="0.1" :max="1.0" :step="0.1"
                    show-input input-size="small"></el-slider>
                </div>
              </el-col>
            </el-row>
          </div>
        </el-tab-pane>
      </el-tabs>

      <div class="processing-actions">
        <el-button type="primary" @click="processData" :loading="processing">
          <i class="el-icon-caret-right"></i>
          开始处理
        </el-button>
        <el-button @click="resetConfig">
          <i class="el-icon-refresh"></i>
          重置配置
        </el-button>
      </div>
    </el-card>

    <!-- 处理结果 -->
    <el-card v-if="processedData.length > 0" class="result-card" shadow="hover">
      <div slot="header" class="card-header">
        <span><i class="el-icon-success"></i> 处理结果</span>
        <el-tag type="success">{{ processedData.length }} 条记录</el-tag>
      </div>

      <div class="result-comparison">
        <el-row :gutter="20">
          <el-col :span="12">
            <div class="comparison-item">
              <h4>处理前</h4>
              <div class="comparison-stats">
                <div class="stat-item">
                  <span class="stat-label">记录数：</span>
                  <span class="stat-value">{{ rawData.length }}</span>
                </div>
                <div class="stat-item">
                  <span class="stat-label">特征数：</span>
                  <span class="stat-value">{{ Object.keys(rawData[0] || {}).length }}</span>
                </div>
                <div class="stat-item">
                  <span class="stat-label">缺失值：</span>
                  <span class="stat-value">{{ dataQuality.missingCount }}</span>
                </div>
              </div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="comparison-item">
              <h4>处理后</h4>
              <div class="comparison-stats">
                <div class="stat-item">
                  <span class="stat-label">记录数：</span>
                  <span class="stat-value">{{ processedData.length }}</span>
                </div>
                <div class="stat-item">
                  <span class="stat-label">特征数：</span>
                  <span class="stat-value">{{ Object.keys(processedData[0] || {}).length }}</span>
                </div>
                <div class="stat-item">
                  <span class="stat-label">数据质量：</span>
                  <span class="stat-value improved">优化</span>
                </div>
              </div>
            </div>
          </el-col>
        </el-row>
      </div>

      <div class="result-actions">
        <el-button type="success" @click="downloadProcessedData">
          <i class="el-icon-download"></i>
          下载处理后数据
        </el-button>
        <el-button @click="previewProcessedData">
          <i class="el-icon-view"></i>
          预览处理后数据
        </el-button>
      </div>
    </el-card>

    <!-- 处理进度 -->
    <el-dialog title="数据处理中" :visible.sync="processing" width="400px" :close-on-click-modal="false"
      :close-on-press-escape="false">
      <div class="processing-progress">
        <el-progress :percentage="processingProgress"
          :status="processingProgress === 100 ? 'success' : null"></el-progress>
        <p class="progress-text">{{ processingStatus }}</p>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Papa from 'papaparse'

export default {
  name: 'DataProcessing',
  data() {
    return {
      uploadedFile: null,
      rawData: [],
      processedData: [],
      processing: false,
      processingProgress: 0,
      processingStatus: '',
      activeTab: 'cleaning',

      // 数据处理配置
      processingConfig: {
        missingValues: 'fillMean',
        outlierHandling: ['removeOutliers'],
        outlierThreshold: 3,
        timeFeatures: ['hour', 'dayOfWeek'],
        lagFeatures: ['lag1', 'lag24'],
        rollingStats: ['mean'],
        normalization: 'standardize',
        featureSelection: ['correlation'],
        correlationThreshold: 0.9
      },

      // 数据质量
      dataQuality: {
        completeness: 100,
        missingCount: 0
      }
    }
  },

  methods: {
    handleFileUpload(file) {
      this.uploadedFile = file
      this.parseFile(file)
      return false // 阻止默认上传
    },

    parseFile(file) {
      const reader = new FileReader()
      reader.onload = (e) => {
        try {
          if (file.name.endsWith('.csv')) {
            Papa.parse(e.target.result, {
              header: true,
              dynamicTyping: true,
              skipEmptyLines: true,
              complete: (results) => {
                this.rawData = results.data
                // console.log('CSV数据解析成功:', results.data.slice(0, 10))
                this.calculateDataQuality()
                this.$message.success('数据上传成功!')
              },
              error: (error) => {
                this.$message.error('CSV解析失败: ' + error.message)
              }
            })
          } else {
            // 处理Excel文件的逻辑
            this.$message.info('Excel文件解析功能开发中...')
          }
        } catch (error) {
          this.$message.error('文件解析失败: ' + error.message)
        }
      }
      reader.readAsText(file)
    },

    calculateDataQuality() {
      if (this.rawData.length === 0) return

      let missingCount = 0
      const totalCells = this.rawData.length * Object.keys(this.rawData[0]).length

      this.rawData.forEach(row => {
        Object.values(row).forEach(value => {
          if (value === null || value === undefined || value === '') {
            missingCount++
          }
        })
      })

      this.dataQuality = {
        completeness: ((totalCells - missingCount) / totalCells) * 100,
        missingCount: missingCount
      }
    },

    async processData() {
      this.processing = true
      this.processingProgress = 0
      this.processingStatus = '开始处理数据...'

      try {
        // 模拟处理过程
        await this.simulateProcessing()

        // 实际处理逻辑
        let data = JSON.parse(JSON.stringify(this.rawData))

        // 数据清洗
        this.processingStatus = '进行数据清洗...'
        this.processingProgress = 20
        data = this.cleanData(data)

        // 特征工程
        this.processingStatus = '进行特征工程...'
        this.processingProgress = 50
        data = this.engineerFeatures(data)

        // 数据标准化
        this.processingStatus = '进行数据标准化...'
        this.processingProgress = 80
        data = this.normalizeData(data)

        this.processingStatus = '处理完成!'
        this.processingProgress = 100

        this.processedData = data

        setTimeout(() => {
          this.processing = false
          this.$message.success('数据处理完成!')
        }, 1000)

      } catch (error) {
        this.processing = false
        this.$message.error('数据处理失败: ' + error.message)
      }
    },

    async simulateProcessing() {
      return new Promise(resolve => {
        setTimeout(resolve, 500)
      })
    },

    cleanData(data) {
      // 简化的数据清洗逻辑
      if (this.processingConfig.missingValues === 'drop') {
        data = data.filter(row => {
          return Object.values(row).every(val => val !== null && val !== undefined && val !== '')
        })
      }

      if (this.processingConfig.outlierHandling.includes('removeOutliers')) {
        // 简化的异常值处理
        const values = data.map(row => row.value).filter(val => !isNaN(val))
        const mean = values.reduce((a, b) => a + b, 0) / values.length
        const std = Math.sqrt(values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / values.length)
        const threshold = this.processingConfig.outlierThreshold * std

        data = data.filter(row => {
          return Math.abs(row.value - mean) <= threshold
        })
      }

      return data
    },

    engineerFeatures(data) {
      // 简化的特征工程逻辑
      return data.map((row, index) => {
        const newRow = { ...row }

        if (this.processingConfig.timeFeatures.includes('hour')) {
          newRow.hour_feature = Math.floor(row.minute / 60)
        }

        if (this.processingConfig.timeFeatures.includes('isWeekend')) {
          newRow.is_weekend = row.week === 6 || row.week === 0 ? 1 : 0
        }

        if (this.processingConfig.lagFeatures.includes('lag1') && index > 0) {
          newRow.lag1_value = data[index - 1].value
        }

        return newRow
      })
    },

    normalizeData(data) {
      // 简化的标准化逻辑
      if (this.processingConfig.normalization === 'standardize') {
        const values = data.map(row => row.value)
        const mean = values.reduce((a, b) => a + b, 0) / values.length
        const std = Math.sqrt(values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / values.length)

        return data.map(row => ({
          ...row,
          value_normalized: (row.value - mean) / std
        }))
      }

      return data
    },

    resetConfig() {
      this.processingConfig = {
        missingValues: 'fillMean',
        outlierHandling: ['removeOutliers'],
        outlierThreshold: 3,
        timeFeatures: ['hour', 'dayOfWeek'],
        lagFeatures: ['lag1', 'lag24'],
        rollingStats: ['mean'],
        normalization: 'standardize',
        featureSelection: ['correlation'],
        correlationThreshold: 0.9
      }
    },

    downloadProcessedData() {
      const csv = Papa.unparse(this.processedData)
      const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
      const link = document.createElement('a')
      const url = URL.createObjectURL(blob)
      link.setAttribute('href', url)
      link.setAttribute('download', 'processed_data.csv')
      link.style.visibility = 'hidden'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    },

    previewProcessedData() {
      // 这里可以打开一个新的预览对话框
      this.$message.info('预览功能开发中...')
    },

    formatFileSize(bytes) {
      if (bytes === 0) return '0 Bytes'
      const k = 1024
      const sizes = ['Bytes', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },

    getTemperatureClass(temperature) {
      if (temperature < 0) return 'cold'
      if (temperature > 25) return 'hot'
      return 'normal'
    }
  }
}
</script>

<style scoped>
.data-processing-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  background: #f5f7fa;
  min-height: 100vh;
}

.page-header {
  text-align: center;
  margin-bottom: 30px;
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 10px;
  color: white;
}

.page-title {
  font-size: 28px;
  font-weight: bold;
  margin-bottom: 10px;
}

.page-subtitle {
  font-size: 16px;
  opacity: 0.9;
  margin: 0;
}

.upload-card,
.preview-card,
.processing-card,
.result-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: bold;
  font-size: 16px;
}

.upload-dragger {
  width: 100%;
}

.uploaded-file-info {
  margin-top: 15px;
  padding: 10px;
  background: #f0f9ff;
  border-radius: 5px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.file-size {
  color: #666;
  font-size: 14px;
}

.data-table-container {
  overflow-x: auto;
}

.number-cell {
  font-weight: bold;
  color: #409eff;
}

.temperature-cell {
  font-weight: bold;
}

.temperature-cell.cold {
  color: #409eff;
}

.temperature-cell.hot {
  color: #f56c6c;
}

.temperature-cell.normal {
  color: #67c23a;
}

.stats-row {
  margin-bottom: 20px;
}

.stats-card {
  text-align: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.stats-item {
  padding: 20px;
}

.stats-value {
  font-size: 32px;
  font-weight: bold;
  margin-bottom: 10px;
}

.stats-label {
  font-size: 14px;
  opacity: 0.9;
}

.processing-options {
  padding: 20px 0;
}

.processing-options h4 {
  margin-bottom: 15px;
  color: #333;
  font-weight: bold;
}

.outlier-config,
.lag-config,
.feature-config {
  margin-top: 15px;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 5px;
}

.processing-actions {
  text-align: center;
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid #e4e7ed;
}

.result-comparison {
  margin-bottom: 20px;
}

.comparison-item {
  padding: 20px;
  border-radius: 8px;
  background: #f8f9fa;
}

.comparison-item h4 {
  margin-bottom: 15px;
  color: #333;
  font-weight: bold;
}

.comparison-stats {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.stat-label {
  color: #666;
}

.stat-value {
  font-weight: bold;
  color: #333;
}

.stat-value.improved {
  color: #67c23a;
}

.result-actions {
  text-align: center;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #e4e7ed;
}

.processing-progress {
  text-align: center;
  padding: 20px;
}

.progress-text {
  margin-top: 15px;
  color: #666;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .data-processing-container {
    padding: 10px;
  }

  .page-title {
    font-size: 24px;
  }

  .stats-value {
    font-size: 24px;
  }
}
</style>